/**
 * 
 */
package com.google.code.cisx.wfe;

import java.util.UUID;

import com.google.code.cisx.wfe.api.WorkflowEngine;
import com.google.code.cisx.wfe.api.WorkflowException;
import com.google.code.cisx.wfe.events.CaseEvent;
import com.google.code.cisx.wfe.events.EventManager;
import com.google.code.cisx.wfe.events.WorkItemEvent;
import com.google.code.cisx.wfe.events.CaseEvent.CaseEventType;
import com.google.code.cisx.wfe.events.WorkItemEvent.WorkItemEventType;
import com.google.code.cisx.wfe.model.Activity;
import com.google.code.cisx.wfe.model.Case;
import com.google.code.cisx.wfe.model.Place;
import com.google.code.cisx.wfe.model.Resource;
import com.google.code.cisx.wfe.model.State;
import com.google.code.cisx.wfe.model.Token;
import com.google.code.cisx.wfe.model.Transition;
import com.google.code.cisx.wfe.model.WorkItem;

/**
 * @author <a href='mailto:rthakur@bravurasolutions.com'>Rahul Thakur</a>
 * @since 1.0
 * @version $Id$
 */
public class DefaultWorkflowEngine implements WorkflowEngine {

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#query(java.util.UUID,
     *      com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public State query(UUID kaseId, Resource resource) throws WorkflowException {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#submit(com.google.code.cisx
     *      .wfe.model.Case, com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public <D> WorkItem<D> submit(Case<D> kase, Resource resource)
            throws WorkflowException {
        EventManager.getInstance().dispatchEvent(
                new CaseEvent(kase, CaseEventType.CASE_SUBMITTED));
        Place<?> source = kase.getSource();
        source.addToken(new Token<D>() {
            @Override
            public D getData() {
                return (D) (new UserData());
            }
        });
        return new WorkItem<D>(kase, kase.getInitialTransition());
    }

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#close(com.google.code.cisx.wfe.model.Case,
     *      com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public <D> void close(Case<D> kase, Resource resource)
            throws WorkflowException {
        // TODO Auto-generated method stub

    }

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#open(com.google.code.cisx.wfe.model.WorkItem,
     *      com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public Activity open(WorkItem wi, Resource resource)
            throws WorkflowException {
        EventManager.getInstance().dispatchEvent(
                new WorkItemEvent(wi, WorkItemEventType.WORKITEM_ACTIVATED));

        Activity activity = new Activity(wi, resource);
        activity.setActive(true);
        return activity;
    }

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#resume(com.google.code.cisx.wfe.model.Case,
     *      com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public <D> void resume(Case<D> kase, Resource resource)
            throws WorkflowException {
        // TODO Auto-generated method stub

    }

    /**
     * {@inheritDoc}
     * 
     * @see com.google.code.cisx.wfe.api.WorkflowEngine#suspend(com.google.code.cisx.wfe.model.Case,
     *      com.google.code.cisx.wfe.model.Resource)
     */
    @Override
    public <D> void suspend(Case<D> kase, Resource resource)
            throws WorkflowException {
        // TODO Auto-generated method stub

    }

    @Override
    public void close(Activity activity, Resource resource)
            throws WorkflowException {
        // TODO: Implement!
        activity = null; // Activity is not available now.
    }

    @Override
    public void fire(Transition transition, Resource resource)
            throws WorkflowException {
        if (transition.isEnabled()) {
            transition.getTransitionProcessor().process(transition);
        } else {
            throw new WorkflowException(
                    "Unable to fire a Transition which is not yet enabled.");
        }

    }

}
